#include "logTraffic.h"

#include "FoICMPstruct.h"
#include <stdio.h>

FILE *logfile;
unsigned char logType;

void InitLog (char* filname, unsigned char logDetails)
{
    logfile=fopen(filname,"w");
    if(logfile==NULL)
        printf("Unable to create file.");
    else
        logType = logDetails;
}

void CloseLog ()
{
    logType = 0;
    fclose(logfile);
}

void PrintIpHeader (unsigned char* Buffer, int Size)
{
    IPV4_HDR *iphdr;
    unsigned short iphdrlen;
    struct sockaddr_in source,dest;

    iphdr = (IPV4_HDR *)Buffer;
    iphdrlen = iphdr->ip_header_len*4;

    memset(&source, 0, sizeof(source));
    source.sin_addr.s_addr = iphdr->ip_srcaddr;

    memset(&dest, 0, sizeof(dest));
    dest.sin_addr.s_addr = iphdr->ip_destaddr;

    fprintf(logfile,"\n");
    fprintf(logfile,"IP Header\n");
    fprintf(logfile,"   |-IP Version        : %d\n",(unsigned int)iphdr->ip_version);
    fprintf(logfile,"   |-IP Header Length  : %d DWORDS or %d Bytes\n",(unsigned int)iphdr->ip_header_len,((unsigned int)(iphdr->ip_header_len))*4);
    fprintf(logfile,"   |-Type Of Service   : %d\n",(unsigned int)iphdr->ip_tos);
    fprintf(logfile,"   |-IP Total Length   : %d  Bytes(Size of Packet)\n",ntohs(iphdr->ip_total_length));
    fprintf(logfile,"   |-Identification    : %d\n",ntohs(iphdr->ip_id));
    fprintf(logfile,"   |-Reserved ZERO Field   : %d\n",(unsigned int)iphdr->ip_reserved_zero);
    fprintf(logfile,"   |-Dont Fragment Field   : %d\n",(unsigned int)iphdr->ip_dont_fragment);
    fprintf(logfile,"   |-More Fragment Field   : %d\n",(unsigned int)iphdr->ip_more_fragment);
    fprintf(logfile,"   |-TTL      : %d\n",(unsigned int)iphdr->ip_ttl);
    fprintf(logfile,"   |-Protocol : %d\n",(unsigned int)iphdr->ip_protocol);
    fprintf(logfile,"   |-Checksum : %d\n",ntohs(iphdr->ip_checksum));
    fprintf(logfile,"   |-Source IP        : %s\n",inet_ntoa(source.sin_addr));
    fprintf(logfile,"   |-Destination IP   : %s\n",inet_ntoa(dest.sin_addr));
}

void PrintTcpPacket(unsigned char* Buffer, int Size)
{
    unsigned short iphdrlen;
    IPV4_HDR *iphdr;
    TCP_HDR  *tcpheader;

    iphdr = (IPV4_HDR *)Buffer;
    iphdrlen = iphdr->ip_header_len*4;

    tcpheader=(TCP_HDR*)(Buffer+iphdrlen);

    fprintf(logfile,"\n\n***********************TCP Packet*************************\n");

    PrintIpHeader(Buffer,Size);

    fprintf(logfile,"\n");
    fprintf(logfile,"TCP Header\n");
    fprintf(logfile,"   |-Source Port      : %u\n",ntohs(tcpheader->source_port));
    fprintf(logfile,"   |-Destination Port : %u\n",ntohs(tcpheader->dest_port));
    fprintf(logfile,"   |-Sequence Number    : %u\n",(unsigned int)ntohl(tcpheader->sequence));
    fprintf(logfile,"   |-Acknowledge Number : %u\n",(unsigned int)ntohl(tcpheader->acknowledge));
    fprintf(logfile,"   |-Header Length      : %d DWORDS or %d BYTES\n"
            ,(unsigned int)tcpheader->data_offset,(unsigned int)tcpheader->data_offset*4);
    fprintf(logfile,"   |-CWR Flag : %d\n",(unsigned int)tcpheader->cwr);
    fprintf(logfile,"   |-ECN Flag : %d\n",(unsigned int)tcpheader->ecn);
    fprintf(logfile,"   |-Urgent Flag          : %d\n",(unsigned int)tcpheader->urg);
    fprintf(logfile,"   |-Acknowledgement Flag : %d\n",(unsigned int)tcpheader->ack);
    fprintf(logfile,"   |-Push Flag            : %d\n",(unsigned int)tcpheader->psh);
    fprintf(logfile,"   |-Reset Flag           : %d\n",(unsigned int)tcpheader->rst);
    fprintf(logfile,"   |-Synchronise Flag     : %d\n",(unsigned int)tcpheader->syn);
    fprintf(logfile,"   |-Finish Flag          : %d\n",(unsigned int)tcpheader->fin);
    fprintf(logfile,"   |-Window         : %d\n",ntohs(tcpheader->window));
    fprintf(logfile,"   |-Checksum       : %d\n",ntohs(tcpheader->checksum));
    fprintf(logfile,"   |-Urgent Pointer : %d\n",tcpheader->urgent_pointer);
    fprintf(logfile,"\n");
    fprintf(logfile,"                        DATA Dump                         ");
    fprintf(logfile,"\n");

    fprintf(logfile,"IP Header\n");
    PrintData(Buffer,iphdrlen);

    fprintf(logfile,"TCP Header\n");
    PrintData(Buffer+iphdrlen,tcpheader->data_offset*4);

    fprintf(logfile,"Data Payload\n");
    PrintData(Buffer+iphdrlen+tcpheader->data_offset*4
            ,(Size-tcpheader->data_offset*4-iphdr->ip_header_len*4));

    fprintf(logfile,"\n###########################################################");
}

void PrintUdpPacket(unsigned char *Buffer,int Size)
{
    unsigned short iphdrlen;
    IPV4_HDR *iphdr;
    UDP_HDR  *udpheader;

    iphdr = (IPV4_HDR *)Buffer;
    iphdrlen = iphdr->ip_header_len*4;

    udpheader = (UDP_HDR *)(Buffer + iphdrlen);

    fprintf(logfile,"\n\n***********************UDP Packet*************************\n");

    PrintIpHeader(Buffer,Size);

    fprintf(logfile,"\nUDP Header\n");
    fprintf(logfile,"   |-Source Port      : %d\n",ntohs(udpheader->source_port));
    fprintf(logfile,"   |-Destination Port : %d\n",ntohs(udpheader->dest_port));
    fprintf(logfile,"   |-UDP Length       : %d\n",ntohs(udpheader->udp_length));
    fprintf(logfile,"   |-UDP Checksum     : %d\n",ntohs(udpheader->udp_checksum));

    fprintf(logfile,"\n");
    fprintf(logfile,"IP Header\n");
    PrintData(Buffer,iphdrlen);

    fprintf(logfile,"UDP Header\n");
    PrintData(Buffer+iphdrlen,sizeof(UDP_HDR));

    fprintf(logfile,"Data Payload\n");
    PrintData(Buffer+iphdrlen+sizeof(UDP_HDR)
        ,(Size - sizeof(UDP_HDR) - iphdr->ip_header_len*4));

    fprintf(logfile,"\n###########################################################");
}

void PrintIcmpPacket(unsigned char* Buffer , int Size)
{
    unsigned short iphdrlen;
    IPV4_HDR *iphdr;
    ICMP_HDR *icmpheader;

    iphdr = (IPV4_HDR *)Buffer;
    iphdrlen = iphdr->ip_header_len*4;

    icmpheader=(ICMP_HDR*)(Buffer+iphdrlen);

    fprintf(logfile,"\n\n***********************ICMP Packet*************************\n");
    PrintIpHeader(Buffer,Size);

    fprintf(logfile,"\n");

    fprintf(logfile,"ICMP Header\n");
    fprintf(logfile,"   |-Type : %d",(unsigned int)(icmpheader->type));

    if((unsigned int)(icmpheader->type)==11) fprintf(logfile,"  (TTL Expired)\n");
    else if((unsigned int)(icmpheader->type)==0) fprintf(logfile,"  (ICMP Echo Reply)\n");


    fprintf(logfile,"   |-Code : %d\n",(unsigned int)(icmpheader->code));
    fprintf(logfile,"   |-Checksum : %d\n",ntohs(icmpheader->checksum));
    fprintf(logfile,"   |-ID       : %d\n",ntohs(icmpheader->id));
    fprintf(logfile,"   |-Sequence : %d\n",ntohs(icmpheader->seq));
    fprintf(logfile,"\n");

    fprintf(logfile,"IP Header\n");
    PrintData(Buffer,iphdrlen);

    fprintf(logfile,"UDP Header\n");
    PrintData(Buffer+iphdrlen,sizeof(ICMP_HDR));

    fprintf(logfile,"Data Payload\n");
    PrintData(Buffer+iphdrlen+sizeof(ICMP_HDR)
            ,(Size - sizeof(ICMP_HDR) - iphdr->ip_header_len*4));

    fprintf(logfile,"\n###########################################################");
}

void PrintData (unsigned char* data , int Size)
{
    int i,j;
    
    for(i=0 ; i < Size ; i++)
    {
        if( i!=0 && i%16==0)   //if one line of hex printing is complete...
        {
            fprintf(logfile,"         ");
            for(j=i-16 ; j<i ; j++)
            {
                if(data[j]>=32 && data[j]<=128)
                    fprintf(logfile,"%c",(unsigned char)data[j]); //if its a number or alphabet

                else
                    fprintf(logfile,"."); //otherwise print a dot
            }
            fprintf(logfile,"\n");
        }

        if(i%16==0) fprintf(logfile,"   ");

        fprintf(logfile," %02X",(unsigned int)data[i]);

        if( i==Size-1)  //print the last spaces
        {
            for(j=0;j<15-i%16;j++) fprintf(logfile,"   "); //extra spaces

            fprintf(logfile,"         ");

            for(j=i-i%16 ; j<=i ; j++)
            {
                if(data[j]>=32 && data[j]<=128)
                    fprintf(logfile,"%c",(unsigned char)data[j]);
                else
                    fprintf(logfile,".");
            }
            fprintf(logfile,"\n");
        }
    }
}


